package mtm.ui.job;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Locale;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.border.LineBorder;

import mtm.constants.Constants;
import mtm.date.MtmDate;
import mtm.db.DatabaseHandler;
import mtm.db.Job;
import mtm.ui.MainFrame;
import mtm.ui.misc.ColorLabel;
import mtm.ui.misc.ImageChooser;
import mtm.ui.misc.TimeComboBox;
import mtm.ui.misc.ColorLabel.MouseClickedListener;
import mtm.ui.panel.MonthPanel;
import mtm.ui.panel.WeekPanel;

import com.toedter.calendar.JDateChooser;


/**
 * Use to insert informaton of new job and display
 * information of jobs 
 * @author CondorHero89
 *
 */
public class JobFrame extends JFrame {
	
	private DatabaseHandler handler = DatabaseHandler.getInstance();
	
	private JLabel lblName;
	private JLabel lblDate;
	private JLabel lblFrom;
	private JLabel lblIcon;
	private JLabel lblColor;
	private JLabel lblDescription;
	
	private JTextField txtName;
	private JDateChooser dateChooser;
	private TimeComboBox cbFromTime;
	private TimeComboBox cbToTime;
	private JLabel lblDisplayIcon;
	private JButton btnChooseIcon;
	private ImageChooser iconChooser;
	private JTextArea taDescription;
	
	private JButton btnOk;
	private JButton btnCancel;

	private JPanel namePanel;
	private JPanel datePanel;
	private JPanel fromPanel;
	private JPanel iconPanel;
	private JPanel colorPanel;
	private JPanel descriptionPanel;
	
	private Job job = null;

	
	/**
	 * Constructor
	 */
	private JobFrame() {
		super("Thiết lập công việc");
		
		setUpComponents();
		
		// cancel button
		btnCancel = new JButton("Thoát");
		btnCancel.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				dispose();
			}
		});
		
		// ok button
		btnOk = new JButton("Thêm việc");
		btnOk.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				if (isFieldsValid()) {
					insertJob();
					// close after insert a new job
					dispose();
				} else {
					JOptionPane.showMessageDialog(null, "Thông tin chưa hợp lệ");
				}
				
			}
		});
		
		setLayoutAndGUI();
	}


	/**
	 * Constructor
	 * @param job the job to display and modify in this frame
	 */
	public JobFrame(Job job) {
		super("Thông tin về công việc");
		this.job = job;
		
		setUpComponents();
		
		// fill information of this job
		txtName.setText(job.getJobName());
		dateChooser.setDate(job.getStartTime().getDayFormat());
		cbFromTime.setText(job.getStartTime().getTimeFormat());
		cbToTime.setText(job.getEndTime().getTimeFormat());
		if (job.getIcon() != null) {
			Image choosenImage;
			try {
				choosenImage = Toolkit.getDefaultToolkit().createImage(new URL(job.getIcon()));
				lblDisplayIcon.setIcon(new ImageIcon(
					choosenImage.getScaledInstance(
						Constants.JOB_ICON_WIDTH, 
						Constants.JOB_ICON_HEIGHT,
						Image.SCALE_SMOOTH), 
						"abc"));
			} catch (MalformedURLException e1) {
				e1.printStackTrace();
			}
		}
		lblColor.setBackground(new Color(job.getColor()));
		taDescription.setText(job.getDescription());
		
		// delete job button
		btnCancel = new JButton("Xóa");
		btnCancel.setToolTipText("Xóa bỏ công việc này");
		final int jobId = job.getId();
		btnCancel.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				int deleteConfirm = JOptionPane.showConfirmDialog(null, "Xóa công việc?");
				if (deleteConfirm == JOptionPane.OK_OPTION) {
					// remove job from DB
					handler.removeJob(jobId);
					
					// delete in WeekPanel
					if (MainFrame.getInstance().isWeekView()) {
						WeekPanel.getInstance().removeJob(jobId);
					}
					// delete in MonthPanel
					else {
						MonthPanel.getInstance().removeJob(JobFrame.this.job);
					}
					
					// close JobFrame
					dispose();
				}
			}
		});
		
		// update job button
		btnOk = new JButton("Cập nhật");
		btnOk.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent event) {
				if (isFieldsValid()) {
					Job currentJob = getCurrentJob();
					
					// update job in DB
					handler.updateJob(currentJob, jobId);
					
					// update WeekPanel
					if (MainFrame.getInstance().isWeekView()) {
						WeekPanel.getInstance().updateJob(currentJob, jobId);
					}
					// update MonthPanel
					else {
						MonthPanel.getInstance().updateJob(currentJob, JobFrame.this.job);
					}
					
					// close JobFrame
					dispose();
				} else {
					JOptionPane.showMessageDialog(null, "Thông tin không hợp lệ");
				}
				
			}
		});
		
		// set layout and GUI
		setLayoutAndGUI();
	}
	
	
	/**
	 * Constructor
	 * @param date
	 */
	public JobFrame(MtmDate date) {
		this();
		dateChooser.setDate(date.getDayFormat());
	}
	
	
	/**
	 * Set up components in this frame and layout them
	 */
	private void setUpComponents() {
		/*
		 *  labels
		 */
		lblName = new JLabel("Tên việc");
		lblDate = new JLabel("Ngày");
		lblFrom = new JLabel("Thời gian");
		lblIcon = new JLabel("Biểu tượng");
		lblIcon.setToolTipText("Biểu tượng của công việc lúc hiển thị trên lịch");
		lblColor = new JLabel("Màu đại diện");
		lblColor.setOpaque(true);
		lblColor.setToolTipText("Màu sắc thể hiện cho công việc lúc hiển thị trên lịch");
		lblDescription = new JLabel("Ghi chú");
		
		
		/*
		 *  fields
		 */
		// job name
		namePanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
		txtName = new JTextField(20);	
		txtName.setBorder(new LineBorder(Color.red, 2, true));
		
		namePanel.add(txtName);
		
		// date chooser
		datePanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
		dateChooser = new JDateChooser();
		dateChooser.setLocale(new Locale("vi"));
		
		datePanel.add(dateChooser);
		
		// from panel
		fromPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
		cbFromTime = new TimeComboBox();
		cbToTime = new TimeComboBox();
		
		fromPanel.add(cbFromTime);
		fromPanel.add(new JLabel("tới"));
		fromPanel.add(cbToTime);
		
		// icon chooser
		iconPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
		lblDisplayIcon = new JLabel();
		btnChooseIcon = new JButton(new ImageIcon(Constants.DEFAULT_JOB_ICON));
		btnChooseIcon.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				iconChooser.open();
			}
		});
		iconChooser = new ImageChooser();
		iconChooser.addActionListener(new ActionListener() {
			
			// listener for choosing an image
			@Override
			public void actionPerformed(ActionEvent evt) {
				if (evt.getActionCommand() == JFileChooser.APPROVE_SELECTION) {
					Image choosenImage = Toolkit.getDefaultToolkit().createImage(
							iconChooser.getImageUrl());
					lblDisplayIcon.setIcon(
							new ImageIcon(
									choosenImage.getScaledInstance(
									Constants.JOB_ICON_WIDTH, 
									Constants.JOB_ICON_HEIGHT,
									Image.SCALE_SMOOTH), 
									"abc"));
				}
			}
		});
		
		iconPanel.add(lblDisplayIcon);
		iconPanel.add(btnChooseIcon);
		
		// color chooser
		colorPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
		for (final ColorLabel lbl : ColorLabel.JOB_COLOR_LABEL) {
			lbl.setMouseClickedListener(new MouseClickedListener() {
				
				@Override
				public void onMouseClicked() {
					lblColor.setBackground(new Color(lbl.getRGB()));
				}
			});
			colorPanel.add(lbl);
		}
		
		// description
		descriptionPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
		taDescription = new JTextArea(2, 30);
		taDescription.setToolTipText("Đừng ghi chú dài quá ^^");
		taDescription.setBorder(new LineBorder(Color.green, 2, true));
		
		descriptionPanel.add(taDescription);
		
	}


	/**
	 * Set layout and GUI 
	 */
	private void setLayoutAndGUI() {
		
		/*
		 *  set layout
		 */
		JPanel labelPanel = new JPanel();
		labelPanel.setLayout(new GridLayout(6, 1));
		labelPanel.add(lblName);
		labelPanel.add(lblDate);
		labelPanel.add(lblFrom);
		labelPanel.add(lblIcon);
		labelPanel.add(lblColor);
		labelPanel.add(lblDescription);
		
		JPanel fieldPanel = new JPanel();
		fieldPanel.setLayout(new GridLayout(6, 1));
		fieldPanel.add(namePanel);
		fieldPanel.add(datePanel);
		fieldPanel.add(fromPanel);
		fieldPanel.add(iconPanel);
		fieldPanel.add(colorPanel);
		fieldPanel.add(descriptionPanel);
		
		JPanel buttonPanel = new JPanel();
		buttonPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
		buttonPanel.add(btnOk);
		buttonPanel.add(btnCancel);
		// TODO
//		if (job == null || !job.isGeneratedJob()) {
//			buttonPanel.add(btnCancel);
//		}
		
		setLayout(new BorderLayout());
		add(labelPanel, BorderLayout.WEST);
		add(fieldPanel, BorderLayout.CENTER);
		add(buttonPanel, BorderLayout.SOUTH);
		
		
		/*
		 *  show GUI
		 */
		setVisible(true);
		setResizable(false);
		setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		pack();
		setLocationRelativeTo(null);
	}
	
	
	/**
	 * The job is currently display in frame
	 * @return
	 */
	private Job getCurrentJob() {
		Job currentJob = new Job();
		
		// id
		if (this.job != null) {
			currentJob.setId(this.job.getId());
		}
		// job name
		currentJob.setJobName(txtName.getText());
		// start time
		currentJob.setStartTime(MtmDate.createFromDateAndTime( dateChooser.getDate(), (String) cbFromTime.getSelectedItem()) );
		// end time
		currentJob.setEndTime(MtmDate.createFromDateAndTime( dateChooser.getDate(), (String) cbToTime.getSelectedItem()) );
		// icon
		if (lblDisplayIcon.getIcon() != null) {
			if (iconChooser.getImageUrl() != null) {
				currentJob.setIcon(iconChooser.getImageUrl().toString());
			} else {
				currentJob.setIcon(job.getIcon());
			}
		}
		// color
		int currentRGB = lblColor.getBackground().getRGB();
		boolean isDefaultColor = true;
		for (ColorLabel lbl : ColorLabel.JOB_COLOR_LABEL) {
			if (currentRGB == lbl.getRGB()) {
				isDefaultColor = false;
				break;
			}
		}
		if (isDefaultColor) {
			 currentJob.setColor(Constants.DEFAULT_JOB_COLOR);
		} else {
			currentJob.setColor(lblColor.getBackground().getRGB());
		}
		// description
		currentJob.setDescription(taDescription.getText());
		
		return currentJob;
	}


	/**
	 * Insert job to database, after processing input
	 */
	private void insertJob() {
		Job currentJob = getCurrentJob();
		
		// insert in UI
		if (MainFrame.getInstance().isWeekView()) {
			WeekPanel.getInstance().addJob(currentJob);
		} else {
			MonthPanel.getInstance().addJob(currentJob);
		}
		
		// insert in DB
		handler.insertJob(currentJob); 
	}


	/**
	 * Process input from fields in frame 
	 * @return
	 * 		- true: if data of all fields is valid
	 * 		- false: otherwise
	 */
	private boolean isFieldsValid() {
		// start time must smaller than end time
		if(cbFromTime.getSelectedIndex() >= cbToTime.getSelectedIndex()) {
			return false;
		}
		
		// name must not null
		if (txtName.getText().trim().equals("")) {
			return false;
		}
		
		// date of job must not null
		if (dateChooser.getDate() == null) {
			return false;
		}
		
		return true;
	}
	
}
